package online.heycm.platform.oss;

import com.amazonaws.HttpMethod;
import com.amazonaws.services.s3.model.*;

import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

public interface OssService {

    /**
     * 判断bucket是否存在
     *
     * @return true:存在 false:不存在
     */
    boolean isBucketExist();

    /**
     * 创建bucket
     *
     * @return true:创建成功 false:创建失败
     */
    boolean createBucket();

    /**
     * 删除bucket
     *
     * @return true:删除成功 false:删除失败
     */
    boolean deleteBucket();

    /**
     * 获取bucket
     *
     * @return bucket
     */
    Bucket getBucket();

    /**
     * 获取bucket列表
     *
     * @return bucket列表
     */
    List<Bucket> listBuckets();

    /**
     * 设置bucket权限
     *
     * @param acl 权限
     * @return true:设置成功 false:设置失败
     */
    boolean setBucketAcl(AccessControlList acl);

    /**
     * 获取bucket权限
     *
     * @return 权限
     */
    AccessControlList getBucketAcl();

    /**
     * 上传文件对象
     *
     * @param objectName 对象名称
     * @param file       文件
     * @return true:上传成功 false:上传失败
     */
    boolean putObject(String objectName, File file);

    /**
     * 上传文件对象
     *
     * @param objectName 对象名称
     * @param file       文件
     * @param metadata   元数据
     * @return true:上传成功 false:上传失败
     */
    boolean putObject(String objectName, File file, Map<String, String> metadata);

    /**
     * 上传文件对象
     *
     * @param objectName  对象名称
     * @param file        文件
     * @param contentType 内容类型
     * @param metadata    元数据
     * @return true:上传成功 false:上传失败
     */
    boolean putObject(String objectName, File file, String contentType, Map<String, String> metadata);

    /**
     * 上传流对象
     *
     * @param objectName  对象名称
     * @param inputStream 流数据
     * @return true:上传成功 false:上传失败
     */
    boolean putObject(String objectName, InputStream inputStream);

    /**
     * 上传流对象
     *
     * @param objectName  对象名称
     * @param inputStream 流数据
     * @param metadata    元数据
     * @return true:上传成功 false:上传失败
     */
    boolean putObject(String objectName, InputStream inputStream, Map<String, String> metadata);

    /**
     * 上传流对象
     *
     * @param objectName  对象名称
     * @param inputStream 流数据
     * @param contentType 内容类型
     * @param metadata    元数据
     * @return true:上传成功 false:上传失败
     */
    boolean putObject(String objectName, InputStream inputStream, String contentType, Map<String, String> metadata);

    /**
     * 获取对象
     *
     * @param objectName 对象名称
     * @return 对象 InputStream
     */
    S3Object getObject(String objectName);

    /**
     * 删除对象
     *
     * @param objectName 对象名称
     * @return true:删除成功 false:删除失败
     */
    boolean deleteObject(String objectName);

    /**
     * 判断对象是否存在
     *
     * @param objectName 对象名称
     * @return true:存在 false:不存在
     */
    boolean isObjectExist(String objectName);

    /**
     * 获取对象元数据
     *
     * @param objectName 对象名称
     * @return 对象元数据
     */
    ObjectMetadata getObjectMetadata(String objectName);

    /**
     * 复制对象
     *
     * @param sourceObjectName 源对象名称
     * @param targetObjectName 目标对象名称
     * @return true:复制成功 false:复制失败
     */
    boolean copyObject(String sourceObjectName, String targetObjectName);

    /**
     * 获取对象列表
     *
     * @return 对象列表
     */
    List<String> listObject();

    /**
     * 获取对象列表
     *
     * @param maximum 最大数量
     * @return 对象列表
     */
    List<String> listObject(int maximum);

    /**
     * 获取对象列表
     *
     * @param prefix 前缀
     * @return 对象列表
     */
    List<String> listObject(String prefix);

    /**
     * 获取对象列表
     *
     * @param prefix  前缀
     * @param maximum 最大数量
     * @return 对象列表
     */
    List<String> listObject(String prefix, int maximum);

    /**
     * 获取预签名URL，7天有效
     *
     * @param objectName 对象名称
     * @return URL
     */
    String getPresignedUrl(String objectName);

    /**
     * 获取预签名URL
     *
     * @param objectName 对象名称
     * @param seconds    有效时间（最大7天）
     * @return URL
     */
    String getPresignedUrl(String objectName, int seconds);

    /**
     * 获取预签名URL
     *
     * @param objectName 对象名称
     * @param seconds    有效时间（最大7天）
     * @param method     请求方式
     * @return URL
     */
    String getPresignedUrl(String objectName, int seconds, HttpMethod method);

    /**
     * 获取URL (ex: {@link CannedAccessControlList#PublicRead})
     *
     * @param objectName 对象名称
     * @return URL
     */
    String getUrl(String objectName);

    /**
     * 获取上传URL，7天有效
     *
     * @param objectName 对象名称
     * @return URL
     */
    String getPutUrl(String objectName);

    /**
     * 获取上传URL
     *
     * @param objectName 对象名称
     * @param seconds    有效时间（最大7天）
     * @return URL
     */
    String getPutUrl(String objectName, int seconds);

    /**
     * 上传目录，文件名即为对象名
     *
     * @param objectNamePrefix 对象名称前缀
     * @param file             目录
     * @return 是否成功
     */
    boolean uploadDirectory(String objectNamePrefix, File file);

    /**
     * 上传目录，文件名即为对象名（递归子目录）
     *
     * @param objectNamePrefix 对象名称前缀
     * @param file             目录
     * @return 是否成功
     */
    boolean uploadDeepDirectory(String objectNamePrefix, File file);

    /**
     * 下载文件
     *
     * @param objectName 对象名称
     * @param file       文件
     * @return 是否成功
     */
    boolean download(String objectName, File file);
}
